package com.baichen;

import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;
import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;

public class Compiler {
    
    /**
     * 动态编译Java文件
     * @param javaFile 要编译的Java源文件
     * @return 编译后的class文件，如果编译失败则返回null
     */
    public static File compileJavaFile(File javaFile) {
        // 检查输入文件是否存在且为Java文件
        if (javaFile == null || !javaFile.getName().endsWith(".java")) {
            System.err.println("无效的Java文件：" + (javaFile != null ? javaFile.getAbsolutePath() : "null"));
            return null;
        }
        
        // 如果文件不存在，尝试基于当前工作目录构建绝对路径
        if (!javaFile.exists()) {
            File workingDir = new File(System.getProperty("user.dir"));
            File absoluteJavaFile = new File(workingDir, javaFile.getPath());
            if (absoluteJavaFile.exists()) {
                javaFile = absoluteJavaFile;
//                System.out.println("使用基于工作目录的绝对路径：" + javaFile.getAbsolutePath());
            } else {
                System.err.println("Java文件不存在：" + javaFile.getAbsolutePath());
                System.err.println("尝试的绝对路径：" + absoluteJavaFile.getAbsolutePath());
                return null;
            }
        }
        
        // 获取系统Java编译器
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        if (compiler == null) {
            System.err.println("无法获取系统Java编译器，请确保运行环境是JDK而非JRE");
            return null;
        }
        
        try {
            // 查找Maven项目根目录
            File projectRoot = findMavenProjectRoot(javaFile);
            if (projectRoot == null) {
                System.err.println("无法找到Maven项目根目录（pom.xml）");
                return null;
            }

            // 创建target/classes目录
            File targetClassesDir = new File(projectRoot, "target/classes");
            if (!targetClassesDir.exists()) {
                targetClassesDir.mkdirs();
            }

            // 计算相对于src/main/java的包路径
            String packagePath = calculatePackagePath(javaFile, projectRoot);

            // 构造编译命令参数
            String[] compilerArgs = {
                "-d", targetClassesDir.getAbsolutePath(),  // 指定输出目录
                "-cp", System.getProperty("java.class.path"),  // 设置类路径
                javaFile.getAbsolutePath()  // 要编译的文件
            };
            
            // 执行编译
            int result = compiler.run(null, null, null, compilerArgs);
            
            if (result == 0) {
                // 编译成功，构造class文件路径
                String className = javaFile.getName().replace(".java", ".class");
                File classFile = new File(targetClassesDir, packagePath + "/" + className);
                
                if (classFile.exists()) {
//                    System.out.println("编译成功：" + classFile.getAbsolutePath());
                    return classFile;
                } else {
                    System.err.println("编译完成但未找到class文件：" + classFile.getAbsolutePath());
                    return null;
                }
            } else {
                System.err.println("编译失败，错误代码：" + result);
                return null;
            }
        } catch (Exception e) {
            System.err.println("编译过程中发生异常：" + e.getMessage());
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 查找Maven项目根目录（包含pom.xml的目录）
     * @param startFile 开始查找的文件
     * @return Maven项目根目录，如果未找到则返回null
     */
    private static File findMavenProjectRoot(File startFile) {
//        System.out.println("开始查找Maven项目根目录，起始文件：" + startFile.getAbsolutePath());

        // 首先尝试从当前工作目录查找
        File workingDir = new File(System.getProperty("user.dir"));
//        System.out.println("当前工作目录：" + workingDir.getAbsolutePath());

        File workingPom = new File(workingDir, "pom.xml");
        if (workingPom.exists()) {
//            System.out.println("在当前工作目录找到pom.xml：" + workingPom.getAbsolutePath());
            return workingDir;
        }

        // 如果当前工作目录没有pom.xml，从文件路径向上查找
        File currentDir = startFile.getParentFile();

        while (currentDir != null) {
//            System.out.println("检查目录：" + currentDir.getAbsolutePath());
            File pomFile = new File(currentDir, "pom.xml");
//            System.out.println("查找pom.xml文件：" + pomFile.getAbsolutePath() + " - 存在：" + pomFile.exists());

            if (pomFile.exists()) {
//                System.out.println("找到Maven项目根目录：" + currentDir.getAbsolutePath());
                return currentDir;
            }
            currentDir = currentDir.getParentFile();
        }

        System.err.println("未找到Maven项目根目录");
        return null;
    }

    /**
     * 计算Java文件相对于src/main/java的包路径
     * @param javaFile Java源文件
     * @param projectRoot Maven项目根目录
     * @return 包路径，如com/baichen
     */
    private static String calculatePackagePath(File javaFile, File projectRoot) {
        try {
            Path javaFilePath = javaFile.toPath().toAbsolutePath();
            Path srcMainJavaPath = Paths.get(projectRoot.getAbsolutePath(), "src", "main", "java").toAbsolutePath();

//            System.out.println("Java文件路径：" + javaFilePath);
//            System.out.println("src/main/java路径：" + srcMainJavaPath);

            // 计算相对路径
//            Path relativePath = srcMainJavaPath.relativize(javaFilePath);
            Path relativePath = Path.of("com/baichen/complie");
//            System.out.println("相对路径：" + relativePath);

            // 获取包路径（去掉文件名）
            Path parentPath = relativePath.getParent();
            if (parentPath == null) {
                System.out.println("文件在src/main/java根目录，无包路径");
                return "";
            }

            String packagePath = parentPath.toString();
//            System.out.println("包路径：" + packagePath);

            // 统一使用正斜杠作为分隔符
            return packagePath.replace("\\", "/");
        } catch (Exception e) {
            System.err.println("计算包路径时发生错误：" + e.getMessage());
            e.printStackTrace();
            return "";
        }
    }
}
